package cn.good.yan.controller;

import cn.good.yan.myLB.LoadBalancer;
import cn.good.yan.pojo.Bill;
import cn.good.yan.pojo.CommonResult;
import com.netflix.appinfo.InstanceInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.cloud.client.discovery.DiscoveryClient;

import java.net.URI;
import javax.annotation.Resource;
import java.util.List;

/**
 * 演示 - 客户端
 * 1. 模拟客户端 请求 服务端 cloud1-provider-8001 项目
 *
 * 2. RestTemplate - 多种方式请求
 * get 请求：restTemplate.getForObject(url, CommonResult.class)
 * restTemplate.getForEntity  上面只是json信息，这个可以有消息头，等详细信息
 * post请求：restTemplate.postForObject(url, 参数对象, CommonResult.class);
 * restTemplate.postForEntity
 *
 *  3 自定义 Ribbon 负载均衡 轮询
 *
 * @author shengren.yan
 * @create 2023-09-20
 */
@Slf4j
@RestController
@RequestMapping("/k1")
public class OrderController {

    // 第1版本，写死的只请求 8001端口的服务
    // public static final String PaymentSrv_URL = "http://localhost:8001";
    // 第2版本，通过在eureka上注册过的微服务名称调用，
    public static final String PaymentSrv_URL = "http://cloud1-provider";

    public static final String bill = "/bill";

    @Resource
    private RestTemplate restTemplate;

    /**
     * 修改
     * 客户端用浏览器是get请求，但是底层实质发送请求   cloud1-provider-8001 项目 的  bill/add/{id}  接口
     *
     * @return
     */
    @GetMapping("/add/{id}")
    public CommonResult<Bill> create() {
        log.info("客户端调用了 修改接口");
        return restTemplate.getForObject(PaymentSrv_URL + bill + "/add/3", CommonResult.class);
    }

    /**
     * 查询
     * 客户端用浏览器是get请求，但是底层实质发送请求   cloud1-provider-8001 项目 的  bill/get/{id}  接口
     *
     * @return
     */
    @GetMapping("/get/{id}")
    public CommonResult<List<Bill>> getPayment(@PathVariable("id") Long id) {
        log.info("客户端调用了 查询接口" + id);
        return restTemplate.getForObject(PaymentSrv_URL + bill + "/get/" + id, CommonResult.class, id);
    }

    // 2 同上，只是restTemplate.getForEntity方式请求
    @GetMapping("/get2/{id}")
    public CommonResult<List<Bill>> getForEntity(@PathVariable("id") Long id) {
        log.info("客户端调用了2 查询接口" + id);
        ResponseEntity<CommonResult> entity = restTemplate.getForEntity(PaymentSrv_URL + bill + "/get/" + id, CommonResult.class);
        // is2xxSuccess 这个就是常量 200，代表成功
        if (entity.getStatusCode().is2xxSuccessful()) {
            return entity.getBody();
        } else {
            return new CommonResult<>(444, "操作失败");
        }
    }

    /**
     * 新增
     * 客户端用浏览器是get请求，但是底层实质发送请求   cloud1-provider-8001 项目 的  bill/save  接口
     *
     * @return
     */
    @GetMapping("/save")
    public CommonResult<List<Bill>> getPayment() {
        Bill bill1 = new Bill();
        bill1.setBillName("aa1");
        bill1.setBillNum(3);
        bill1.setBillCode("ccc");
        bill1.setBillName("ccc1");
        log.info("客户端调用了 新增接口" + bill1);
        return restTemplate.postForObject(PaymentSrv_URL + bill + "/save", bill1, CommonResult.class);
    }


//    gat请求
//    <T> T getForObject(String url, Class<T> responseType, Object... uriVariables);
//
//    <T> T getForObject(String url, Class<T> responseType, Map<String, ?> uriVariables);
//
//    <T> T getForObject(URI url, Class<T> responseType);
//
//    <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Object... uriVariables);
//
//    <T> ResponseEntity<T> getForEntity(String url, Class<T> responseType, Map<String, ?> uriVariables);
//
//    <T> ResponseEntity<T> getForEntity(URI var1, Class<T> responseType);


//    post请求
//    <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);
//
//    <T> T postForObject(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables);
//
//    <T> T postForObject(URI url, @Nullable Object request, Class<T> responseType);
//
//    <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Object... uriVariables);
//
//    <T> ResponseEntity<T> postForEntity(String url, @Nullable Object request, Class<T> responseType, Map<String, ?> uriVariables);
//
//    <T> ResponseEntity<T> postForEntity(URI url, @Nullable Object request, Class<T> responseType);

    @Resource
    private DiscoveryClient discoveryClient;

    @Resource
    private LoadBalancer loadBalancer;

    // 3 自定义 Ribbon 负载均衡 轮询
    @GetMapping("/get3/{id}")
    public CommonResult<List<Bill>> getPaymentLB(@PathVariable("id") Long id) {
        List<ServiceInstance> instances = discoveryClient.getInstances("CLOUD1-PROVIDER");
        if (instances == null || instances.size() <= 0) {
            return null;
        }
        ServiceInstance serviceInstances = loadBalancer.instances(instances);
        URI uri = serviceInstances.getUri();

        log.info("客户端调用了 查询接口" + id);
        return restTemplate.getForObject(uri + bill + "/get/" + id, CommonResult.class, id);
    }


}

